Carregar pacotes

library(sf)
library(ggplot2)
fname <- system.file("shape/nc.shp", package="sf")
nc <- st_read(fname)
## Reading layer `nc' from data source 
##   `C:\Users\Gonzalo\Documents\R\win-library\4.0\sf\shape\nc.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 100 features and 14 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
## Geodetic CRS:  NAD27
ggplot(nc) + geom_sf() 

library(sf)
library(dplyr)
library(leaflet)
library(plotly)
library(highcharter)
library(reactable)
# para o gganimate funcionar perfeitamente, instale também
# install.packages(c("gifski", "av"))
library(gganimate)
library(patchwork)
library(ggrepel)

Bases de dados

escolas_brasilia <- readr::read_rds("../dados/geobr/escolas_brasilia.Rds")
dados_idh_muni <- abjData::pnud_min %>% 
  mutate(code_muni = as.numeric(muni_id))

# unir a base de municipios do geobr com a base de IDH
municipios <- readr::read_rds("../dados/geobr/municipios_todos.rds") %>%
  inner_join(dados_idh_muni)

# municipios <- readr::read_rds("../dados/municipios_tibble.Rds")

# se quiser buscar esses dados com o pacote geobr, 
# o código é o seguinte
# municipios <- geobr::read_municipality()
estado_para_filtrar <- municipios %>%
  dplyr::pull(abbrev_state) %>% 
  unique() %>%
  sample(1)

htmlwidgets

leaflet

O leaflet ajuda a fazer mapas interativos, em uma sintaxe muito parecida com o ggplot2. Você inicia com um mapa vazio e vai adicionando layers.

Mapa de pontos

escolas_brasilia %>%
  # adiciona leaflet vazio
  leaflet() %>%
  # adiciona mapinha
  addTiles() %>%
  # adiciona marcadores
  addMarkers(
    popup = ~ name_school,
    clusterOptions = markerClusterOptions()
  )

Mapa temático

### transformador de numeros em cores
pal <- colorNumeric("YlOrRd", filter(municipios, ano == 2010)$idhm)
pal(0.7)
## [1] "#FA4B29"
pal(0.81)
## [1] "#B90026"
municipios %>% 
  # filtrar para o ano de 2010, e apenas 1 estado
  dplyr::filter(ano == 2010, abbrev_state == estado_para_filtrar) %>% 
  # adiciona mapa vazio
  leaflet() %>% 
  # adiciona mapinha
  addTiles() %>% 
  # adiciona shapes
  addPolygons(
    label = ~muni_nm, 
    weight = 1,
    color = "black",
    fillColor = ~pal(idhm),
    fillOpacity = .8
  )

plotly

https://plot.ly é uma empresa bem grande de visualização de dados.

Eles produzem ferramentas para R, python, JavaScript e têm uma solução própria para fazer dashboards.

Para essa parte, vamos nos limitar ao ggplotly(), que é um transformador de ggplot em plotly:

gg_idhm <- municipios %>% 
  ggplot(aes(x = gini, y = idhm, colour = espvida)) +
  geom_point() +
  facet_wrap(~ano)

plotly::ggplotly(gg_idhm)

highcharter

https://www.highcharts.com também é uma grande empresa de visualização

O {highcharter} é uma adaptação do highcharts para R.

Assim como no plotly, o highcharter tenta se aproximar da linguagem R através do ggplot2. No entanto, a abordagem é diferente: é fornecida uma sintaxe parecida com o ggplot2, com algumas adaptações.

municipios %>% 
  filter(ano == 2010, abbrev_state == estado_para_filtrar) %>% 
  hchart("scatter", hcaes(x = gini, y = idhm, color = espvida))
  • para graficos univariados, basta passar o vetor
# histograma
municipios %>% 
  pull(gini) %>% 
  hchart()
# densidade
municipios %>% 
  pull(gini) %>% 
  density() %>% 
  hchart()

reactable

{reactable} e {DT} são os melhores pacotes para fazer tabelas interativas. Aqui, vamos mostrar o {reactable}

# tabela base

dados_summ <- municipios %>% 
  as_tibble() %>% 
  group_by(ano, abbrev_state) %>% 
  summarise(
    pop = sum(pop),
    gini = mean(gini),
    .groups = "drop"
  ) %>% 
  tidyr::pivot_wider(
    names_from = ano, 
    values_from = c(pop, gini)
  )
# criando a tabela 
dados_summ %>%
  reactable(
    columns = list(
      abbrev_state = colDef("Estado"),
      pop_1991 = colDef("1991", format = colFormat(separators = TRUE)),
      pop_2000 = colDef("2000", format = colFormat(separators = TRUE)),
      pop_2010 = colDef("2010", format = colFormat(separators = TRUE)),
      gini_1991 = colDef("1991", format = colFormat(digits = 3)),
      gini_2000 = colDef("2000", format = colFormat(digits = 3)),
      gini_2010 = colDef("2010", format = colFormat(digits = 3))
    ),
    columnGroups = list(
      colGroup(
        name = "População",
        columns = c("pop_1991", "pop_2000", "pop_2010")
      ),
      colGroup(
        name = "Índice de Gini",
        columns = c("gini_1991", "gini_2000", "gini_2010")
      )
    )
  )

Extensões do ggplot2

ggalt

# geom_encircle é interessante para destacar pontos distantes da nuvem de pontos
library(ggalt)

# abjData::pnud_min

pontos_diferentes <- municipios %>% 
  filter(uf_sigla == "RS", ano == 2010, pop > 4e5)

gg_alt <- municipios %>% 
  filter(uf_sigla == "RS", ano == 2010) %>% 
  ggplot(aes(idhm_e, pop)) +
  geom_point() +
  ggalt::geom_encircle(
    data = pontos_diferentes,
    color = "red", s_shape = .1, expand = .01, size = 3
  )

# ggalt::stat_stepribbon()

gg_alt

gghighlight

Também é possível obter resultados similares usando gghighlight

gg_highlight <- municipios %>% 
  filter(uf_sigla == "RS", ano == 2010) %>% 
  ggplot(aes(idhm_e, pop)) +
  geom_point() +
  gghighlight::gghighlight(
    pop > 4e5,
    label_key = name_muni
  )

gg_highlight

ggrepel

municipios %>% 
  filter(uf_sigla == "RR", ano == 2010) %>% 
  ggplot(aes(idhm_e, idhm_l)) +
  geom_point() +
  geom_label(aes(label = name_muni))

gg_repel <- municipios %>% 
  filter(uf_sigla == "PB", ano == 2010) %>% 
  ggplot(aes(idhm_e, idhm_l)) +
  geom_point() +
  ggrepel::geom_label_repel(aes(label = name_muni), force = 100)

gg_repel

patchwork

Na mesma linha

library(patchwork)

gg_alt + gg_highlight

Na mesma coluna

gg_alt / gg_highlight

gg_alt + gg_highlight + gg_highlight +
  plot_layout(nrow = 2)

Expressões

(gg_alt + gg_highlight) / gg_repel

ggsave("ggplot.svg", gg_highlight)

gganimate

gganimate transforma um conjunto de gráficos em animações. Geralmente é usado para substituir facets por animações.

Gráfico

anim <- municipios %>% 
  filter(abbrev_state == estado_para_filtrar) %>% 
  mutate(ano = as.numeric(ano)) %>% 
  ggplot(aes(rdpc, espvida, size = sqrt(pop))) +
  geom_point() +
  facet_wrap(~abbrev_state) +
  scale_x_log10() +
  # Aqui começa o gganimate
  labs(title = 'Ano: {frame_time}', x = 'Renda', y = 'Expectativa de vida') +
  gganimate::transition_time(ano)
  • mostrar o gif!
gganimate::animate(anim, nframes = 20, width = 800, height = 400)

  • salvar o gif
# criar a pasta para salvar o gif
fs::dir_create("../output")

# melhor se tiver o pacote {gifski} instalado
gganimate::animate(
  anim, 
  width = 800, height = 400, 
  nframes = 20,
  duration = 10, 
  fps = 2, 
  detail = 1,
  gifski_renderer("../output/gif_ggplot.gif")
)
  • salvar em video
# melhor se tiver o pacote {av} instalado
gganimate::animate(
  anim, 
  width = 800, height = 400, 
  nframes = 20,
  duration = 10, 
  fps = 2, 
  detail = 1,
  av_renderer("../output/video_ggplot.mp4")
)

Mapa

### install.packages("transformr")
anim <- municipios %>% 
  filter(abbrev_state == estado_para_filtrar) %>% 
  mutate(ano = as.numeric(ano)) %>% 
  ggplot(aes(fill = idhm)) +
  geom_sf(colour = "black", size = .1) +
  theme_void(12) +
  labs(title = 'Ano: {frame_time}') +
  transition_time(ano) +
  enter_fade()
  • Mostrar o gif!
animate(
  anim, nframes = 20, fps = 8,
  width = 800, height = 400
)
  • Salvar o gif
animate(
  anim, 
  width = 800, height = 400, 
  nframes = 20,
  duration = 5, 
  fps = 4, 
  detail = 1,
  gifski_renderer("../output/gif_mapa.gif")
)